<template>
  <a-spin
    :delay="200"
    tip="加载中..."
    :spinning="loading"
    wrapper-class-name="loading"
    style="height: 100%; width: 100%"
  >
    <a-card v-if="!loading" class="body-container">
      <s-list-form
        :enable-more="config.general.more"
        @change="
          $nextTick(() => {
            $calcTableHeight()
          })
        "
      >
        <template #less>
          <s-dynamic-form :items="config.search.less.items" :form="query"> </s-dynamic-form>
          <slot name="query-less"></slot>
        </template>
        <template #more>
          <s-dynamic-form :items="config.search.more.items" :form="query"> </s-dynamic-form>
          <slot name="query-more"></slot>
        </template>
      </s-list-form>
      <s-tool-bar>
        <template #left>
          <s-button
            v-if="permissions.add"
            icon="plus-outlined"
            type="primary"
            @click="
              () => {
                ;(itemFormValue = {}), $refs.add.open()
              }
            "
          >
            新增
          </s-button>
          <a-popconfirm
            v-if="permissions.delete"
            title="确认删除所选数据？"
            ok-text="是"
            cancel-text="否"
            @confirm="deleteMulti"
          >
            <s-button type="danger" icon="delete-outlined"> 删除 </s-button>
          </a-popconfirm>
          <slot name="toolbar-left"></slot>
        </template>
        <template #right>
          <s-button type="primary" icon="search-outlined" @click="search">查询</s-button>
          <s-button
            style="margin-left: 8px"
            icon="stop-outlined"
            @click="
              () => {
                query = {}
              }
            "
            >重置</s-button
          >
        </template>
        <slot name="toolbar-right"></slot>
      </s-tool-bar>
      <s-table
        ref="table"
        bordered
        :echos="echos"
        :scroll="{ y: tableHeight }"
        :columns="columns"
        :url="config.interface.list"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'action'">
            <a
              v-if="permissions.detail"
              style="margin-right: 8px"
              @click="detail(record.id, $refs.detail)"
            >
              <s-icon type="eye-outlined" />查看
            </a>
            <a
              v-if="permissions.update"
              style="margin-right: 8px"
              @click="detail(record.id, $refs.update)"
            >
              <s-icon type="edit-outlined" />编辑
            </a>
            <a-popconfirm
              v-if="permissions.delete"
              title="确认删除此条数据？"
              ok-text="是"
              cancel-text="否"
              @confirm="deleteById(record.id)"
            >
              <a style="margin-right: 8px"> <s-icon type="delete-outlined" />删除 </a>
            </a-popconfirm>
          </template>
          <slot name="row-action" :column="column" :record="record"></slot>
        </template>
      </s-table>
      <s-dynamic-form-dialog
        ref="add"
        v-model="itemFormValue"
        :width="moduleForm.properties.width"
        :height="moduleForm.properties.height"
        title="添加"
        :form-items="moduleForm.data"
        @save="addItem"
      >
        <template #item="{ properties, type }">
          <slot name="item-add" :properties="properties" :type="type"></slot>
        </template>
      </s-dynamic-form-dialog>
      <s-dynamic-form-dialog
        ref="detail"
        v-model="itemFormValue"
        :width="moduleForm.properties.width"
        :height="moduleForm.properties.height"
        title="详情"
        :form-items="moduleForm.data"
        disabled
      >
        <template #item="{ properties, type }">
          <slot name="item-detail" :properties="properties" :type="type"></slot>
        </template>
        <template v-if="operation">
          <s-form-item label="创建人">
            <s-input v-model="itemFormValue.createByAccount" disabled />
          </s-form-item>
          <s-form-item label="创建时间">
            <s-input v-model="itemFormValue.createDate" disabled />
          </s-form-item>
          <s-form-item label="修改人">
            <s-input v-model="itemFormValue.updateByAccount" disabled />
          </s-form-item>
          <s-form-item label="修改时间">
            <s-input v-model="itemFormValue.updateDate" disabled />
          </s-form-item>
        </template>
      </s-dynamic-form-dialog>
      <s-dynamic-form-dialog
        ref="update"
        v-model="itemFormValue"
        :width="moduleForm.properties.width"
        :height="moduleForm.properties.height"
        title="编辑"
        :form-items="moduleForm.data"
        @save="updateItem"
      >
        <template #item="{ properties, type }">
          <slot name="item-update" :properties="properties" :type="type"></slot>
        </template>
      </s-dynamic-form-dialog>
    </a-card>
  </a-spin>
</template>
<script>
export default {
  name: 'OnlineTable',
  props: {
    actionWidth: {
      required: false,
      type: Number,
      default: 300
    }
  },
  data() {
    return {
      itemFormValue: {},
      moduleForm: {
        data: [],
        properties: {
          height: '0px',
          width: '0px'
        }
      },
      operation: false,
      echos: [],
      loading: true,
      query: {},
      permissions: {
        add: true,
        update: true,
        delete: true,
        detail: true
      },
      config: {
        general: {
          more: false
        },
        search: {
          index: 0,
          less: {
            items: []
          },
          more: {
            items: []
          }
        },
        hooks: {
          query: null
        },
        interface: {
          custom: false,
          add: '',
          update: '',
          list: '',
          delete: '',
          deleteMulti: ''
        }
      },
      columns: []
    }
  },
  created() {
    const moduleId = this.$route.query.id
    // 加载模块...
    this.$api.GET('/code/module/selectOneById', { id: moduleId }).then((res) => {
      if (res.data) {
        this.$api
          .GET('/code/model/selectOneById', { id: res.data.moduleValue.model })
          .then((res2) => {
            if (res2.data) {
              this.init(res.data, res2.data)
            }
          })
      }
    })
  },
  methods: {
    addItem(values, fullValue) {
      const _this = this
      if (this.config.hooks.add) {
        // eslint-disable-next-line no-eval
        eval('(values,fullValue,_this)=>{  ' + this.config.hooks.add + '}')(
          values,
          fullValue,
          _this
        )
      }
      this.$api
        .PUT(this.config.interface.add, values)
        .then((res) => {
          this.$refs.add.close()
          this.search()
          this.$message.info(res.msg)
        })
        .catch(() => {
          this.$refs.add.reset()
        })
    },
    updateItem(values, fullValue) {
      values.id = fullValue.id
      const _this = this
      if (this.config.hooks.update) {
        // eslint-disable-next-line no-eval
        eval('(values,fullValue,_this)=>{  ' + this.config.hooks.update + '}')(
          values,
          fullValue,
          _this
        )
      }
      this.$api
        .PUT(this.config.interface.update, values)
        .then((res) => {
          this.$refs.update.close()
          this.search()
          this.$message.info(res.msg)
        })
        .catch(() => {
          this.$refs.update.reset()
        })
    },
    detail(id, ref) {
      this.$loading(true)
      this.$api
        .GET(this.config.interface.detail, { id: id })
        .then((res) => {
          this.$loading(false)
          if (!res.data) {
            this.$message.warn('数据不存在')
          } else {
            this.itemFormValue = res.data
            ref.open()
          }
        })
        .catch(() => {
          this.$loading(false)
        })
    },
    formatTableColumn(fakeColumns) {
      let newColumn = []
      let echos = []
      fakeColumns.forEach((item) => {
        let newItem = {
          dataIndex: item.echo ? item.dataIndex + 'Name' : item.dataIndex,
          title: item.title,
          width: item.width,
          sorter: item.sorter,
          ellipsis: item.ellipsis
        }
        if (item.echo) {
          echos.push({
            name: item.dataIndex,
            label: item.echoLabel,
            value: item.echoValue,
            url: item.echoUrl
          })
        }
        newColumn.push(newItem)
      })
      newColumn.push({
        title: '操作',
        fixed: 'right',
        key: 'action',
        width: this.actionWidth
      })
      this.echos = echos
      this.columns = newColumn
    },
    init(module, model) {
      try {
        this.operation = model.modelForm.operation == '1'
        this.moduleForm.data = module.moduleForm.data
        this.moduleForm.properties = module.moduleForm.properties
        this.config = module.moduleList.config
        //初始化url
        if (!this.config.interface.custom) {
          let prefix = '/code/onlineForm/'
          //使用通用接口
          this.config.interface.add = prefix + module.id + '/insert'
          this.config.interface.delete = prefix + module.id + '/delete'
          this.config.interface.deleteMulti = prefix + module.id + '/deleteMulti'
          this.config.interface.update = prefix + module.id + '/update'
          this.config.interface.list = prefix + module.id + '/pageList'
          this.config.interface.detail = prefix + module.id + '/selectOneById'
        }
        //初始化权限
        if (module.moduleValue.authCheck == '1') {
          this.permissions.add = this.$hasPermission(
            'skrivet:' + module.moduleValue.code + ':add',
            'and'
          )
          this.permissions.delete = this.$hasPermission(
            'skrivet:' + module.moduleValue.code + ':delete',
            'and'
          )
          this.permissions.detail = this.$hasPermission(
            'skrivet:' + module.moduleValue.code + ':detail',
            'and'
          )
          this.permissions.update = this.$hasPermission(
            'skrivet:' + module.moduleValue.code + ':update',
            'and'
          )
        }
        //初始化column
        let fakeColumns = module.moduleList.tableColumns
        this.formatTableColumn(fakeColumns)
        this.loading = false
        this.$nextTick(() => {
          this.$calcTableHeight()
        })
      } catch (e) {
        console.log(e)
      }
    },
    deleteMulti() {
      const keys = this.$refs.table.getSelectedKeys()
      if (keys.length > 0) {
        this.$loading(true)
        this.$api
          .DELETE(this.config.interface.deleteMulti, { ids: keys.toString() })
          .then(() => {
            this.$loading(false)
            this.search()
          })
          .catch(() => {
            this.$loading(false)
          })
      }
    },
    search() {
      const _this = this
      const query = JSON.parse(JSON.stringify(this.query))
      let putVal = []
      Object.keys(query).forEach((key) => {
        let val = query[key]
        if (val && Array.isArray(val) && val.length == 2) {
          putVal.push({ key: key + 'Start', value: val[0] })
          putVal.push({ key: key + 'End', value: val[1] })
          delete query[key]
        }
      })
      putVal.forEach((item) => {
        query[item.key] = item.value
      })
      if (this.config.hooks.query) {
        // eslint-disable-next-line no-eval
        eval('(query,_this)=>{  ' + this.config.hooks.query + '}')(query, _this)
      }
      this.$refs.table.search(query)
    },
    deleteById(id) {
      this.$loading(true)
      this.$api
        .DELETE(this.config.interface.delete, { id: id })
        .then(() => {
          this.$loading(false)
          this.search()
        })
        .catch(() => {
          this.$loading(false)
        })
    }
  }
}
</script>
<style>
.loading {
  height: 100%;
}
</style>
